#include <sys/types.h>
#include <sys/ipc.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

// 定义两个信号量的名称
char SEM_NAME[] = "process1";
char SEM_NAME2[] = "process2";
// 定义共享内存大小（在本程序中未使用）
#define SHMSZ 27

int main(int argc, char **argv)
{
    char ch;
    int shmid;
    key_t key;
    int fd;
    // 定义两个信号量指针
    sem_t *mutex, *mutex2;

    // 创建并初始化信号量
    // 第一个信号量初始值为 0，用于控制写入操作的开始
    mutex = sem_open(SEM_NAME, O_CREAT, 0777, 0);
    // 第二个信号量初始值为 1，用于控制另一个进程的操作
    mutex2 = sem_open(SEM_NAME2, O_CREAT, 0777, 1);

    // 检查信号量是否创建成功
    if (mutex == SEM_FAILED || mutex2 == SEM_FAILED)
    {
        // 若创建失败，输出错误信息
        perror("unable to execute semaphore");
        // 关闭已打开的信号量
        sem_close(mutex);
        sem_close(mutex2);
        // 终止程序
        exit(-1);
    }

    // 打开文件 a.txt，若文件不存在则创建，以只写模式打开，截断文件内容并追加写入
    fd = open("a.txt", O_CREAT | O_WRONLY | O_TRUNC | O_APPEND);
    if (fd == -1)
    {
        // 若打开文件失败，输出错误信息
        perror("open failed");
        // 关闭信号量
        sem_close(mutex);
        // 终止程序
        exit(-1);
    }

    // 进入无限循环
    while (1)
    {
        // 对第一个信号量执行 P 操作（等待信号量值大于 0）
        sem_wait(mutex);
        // 向文件 a.txt 中写入字符串 "ABC\n"
        write(fd, "ABC\n", sizeof("ABC\n") - 1);
        // 关闭文件
        close(fd);
        // 重新打开文件 a.txt，以追加模式写入
        fd = open("a.txt", O_WRONLY | O_APPEND);
        // 程序休眠 1 秒
        sleep(1);
        // 对第二个信号量执行 V 操作（释放信号量，使信号量值加 1）
        sem_post(mutex2);
    }

    // 关闭第一个信号量
    sem_close(mutex);
    // 删除第一个信号量
    sem_unlink(SEM_NAME);
    // 关闭文件
    close(fd);

    // 程序正常退出
    exit(0);
}